package com.huilian.tool.douyin.applet.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.huilian.tool.common.config.AppletDouYinConfig;
import com.huilian.tool.douyin.applet.service.DouYinAppletPayService;
import com.huilian.tool.douyin.applet.service.DouYinAppletService;
import com.huilian.tool.douyin.util.Sign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service
public class DouYinAppletPayServiceImpl implements DouYinAppletPayService {

    @Resource
    private RestTemplate restTemplate;
    @Resource
    private AppletDouYinConfig appletDouYinConfig;
    @Resource
    private DouYinAppletService douYinAppletService;

    /**
     * 预下单
     *
     * @param outOrderNo  订单号
     * @param totalAmount 支付价格。 单位为[分]
     * @param body        商品描述。 长度限制不超过 128 字节且不超过 42 字符
     * @param validTime   订单过期时间(秒)。最小5分钟，最大2天
     * @param notifyUrl   商户自定义回调地址，必须以 https 开头
     * @return
     */
    @Override
    public JSONObject orderInAdvance(String outOrderNo, Integer totalAmount, String body, Integer validTime, String notifyUrl) {

        StringBuilder url = new StringBuilder(appletDouYinConfig.getDeveloperUrl()).append("ecpay/v1/create_order");
        Map<String, Object> params = new HashMap<>();
        params.put("app_id", appletDouYinConfig.getAppId());
        params.put("out_order_no", outOrderNo);
        params.put("total_amount", totalAmount);
        params.put("subject", body);
        params.put("body", body);
        params.put("valid_time", validTime);
        params.put("notify_url", notifyUrl);
        params.put("sign", Sign.requestSign(params, appletDouYinConfig.getSalt()));

//        System.out.println(JSON.toJSONString(params));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        /**
         * {
         *   "err_tips": "success",
         *   "data": {
         *     "order_id": "N718395******1079592",
         *     "order_token": "CgwIARDGJRiuMiABKAESTgpMyIYEKZr******88Yq7xoA.L",
         *     "url": ""
         *   },
         *   "err_no": 0
         * }
         */

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers);
        return restTemplate.postForObject(url.toString(), entity, JSONObject.class);
    }

    @Override
    public JSONObject orderQueryPayResult(String outOrderNo) {
        StringBuilder url = new StringBuilder(appletDouYinConfig.getDeveloperUrl()).append("ecpay/v1/query_order");
        Map<String, Object> params = new HashMap<>();
        params.put("app_id", appletDouYinConfig.getAppId());
        params.put("out_order_no", outOrderNo);
        params.put("sign", Sign.requestSign(params, appletDouYinConfig.getSalt()));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers);
        return restTemplate.postForObject(url.toString(), entity, JSONObject.class);
    }

    /**
     * 抖音支付回调
     *
     * @param jsonObject
     */
    @Override
    public JSONObject payNotify(JSONObject jsonObject) {
        log.info("抖音支付回调默认处理");

        log.info("jsonObject:" + JSON.toJSONString(jsonObject));

        // Unix 时间戳
        String timestamp = jsonObject.getString("timestamp");
        // 随机数
        String nonce = jsonObject.getString("nonce");
        // 回调类型标记，支付成功回调为"payment"
        String msg = jsonObject.getString("msg");
        // 签名
        String type = jsonObject.getString("type");
        // 订单信息
        String msg_signature = jsonObject.getString("msg_signature");

        /**
         * {
         *   "timestamp": "1602507471",
         *   "nonce": "797",
         *   "msg": "{\"appid\":\"tt07e3715e98c9aac0\",\"cp_orderno\":\"out_order_no_1\",\"cp_extra\":\"\",\"way\":\"2\",\"payment_order_no\":\"2021070722001450071438803941\",\"total_amount\":9980,\"status\":\"SUCCESS\",\"seller_uid\":\"69631798443938962290\",\"extra\":\"null\",\"item_id\":\"\",\"order_id\":\"N71016888186626816\"}",
         *   "msg_signature": "52fff5f7a4bf4a921c2daf83c75cf0e716432c73",
         *   "type": "payment"
         * }
         */

        List<String> params = new ArrayList<>();
        params.add(timestamp);
        params.add(nonce);
        params.add(msg);
        params.add(appletDouYinConfig.getToken());

        String newSign = Sign.callbackSign(params);
        JSONObject resultJSON = new JSONObject();
        if (msg_signature.equalsIgnoreCase(newSign)) {
            JSONObject msgJSON = JSON.parseObject(msg);

            resultJSON.put("err_no", 0);
            resultJSON.put("err_tips", "success");
            resultJSON.put("type", type);
            resultJSON.put("data", msgJSON);
            return resultJSON;
        } else {
            log.error("抖音支付回调签名校验不通过" + JSON.toJSONString(jsonObject));
            throw new RuntimeException("抖音支付回调签名校验不通过");
//            resultJSON.put("err_no", 400);
//            resultJSON.put("err_tips", "business fail");
//            return resultJSON;
        }
    }

    @Override
    public JSONObject refund(String outOrderNo, String refundOutOrderNo) {
        Map<String, Object> params = new HashMap<>();
        params.put("app_id", appletDouYinConfig.getAppId());
        params.put("out_order_no", outOrderNo);
        params.put("out_refund_no", refundOutOrderNo);
        params.put("reason", "测试接口");
        params.put("refund_amount", 100);
        params.put("sign", Sign.requestSign(params, appletDouYinConfig.getSalt()));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(params, headers);
        return restTemplate.postForObject(appletDouYinConfig.getDeveloperUrl() + "ecpay/v1/create_refund", entity, JSONObject.class);
    }
}
